#include "ArrowNode.h"

ArrowNode* ArrowNode::createArrowNode(Arrow *arrow, float angle, Node *gameLayer) {
	ArrowNode *arrowNode = new ArrowNode();
	if (arrowNode && arrowNode->initArrowNode(arrow, angle, gameLayer)) {
		arrowNode->autorelease();
		return arrowNode;
	}
	CC_SAFE_DELETE(arrowNode);
	return nullptr;
}

bool ArrowNode::initArrowNode(Arrow *arrow, float angle, Node *gameLayer) {
	this->setRotation(angle);
	m_arrow = arrow;
	m_gameLayer = gameLayer;
	m_showSprite = Sprite::createWithSpriteFrameName(arrow->getArrowFileName());
	Rect box = m_showSprite->getBoundingBox();
	m_collisionPoint = Vec2(box.getMaxX(), box.getMidY());
	if (m_arrow->getMagicArrow() == MagicArrow::FIRE) {
		auto particle = ParticleSystemQuad::create(FIREARROWPARTICLE_NAME);
		particle->setPosition(m_collisionPoint);
		this->addChild(particle);
	}
	this->addChild(m_showSprite);
	this->schedule([=](float) {
		int airSpeed = AIRSPEED_COEFFICIENT(this->getAirSpeed());
		float radian = CC_DEGREES_TO_RADIANS(angle);
		this->setPosition(this->getPosition() + Vec2(airSpeed * cos(radian), -airSpeed * sin(radian)));

		if (this->getPositionX() > SCREEN.width + m_showSprite->getContentSize().width * 0.5 || this->getPositionY() > SCREEN.height + m_showSprite->getContentSize().height * 0.5 || this->getPositionY() < -m_showSprite->getContentSize().width * 0.5) {
			auto gameLayer = dynamic_cast<GameLayer *>(m_gameLayer);
			gameLayer->getArrowArrayRM()->addObject(this);
			this->removeFromParent();
		}
	}, 0.01f, "ArrowShoot");
	return true;
}

Rect ArrowNode::getCollisionArea() {
	Rect rect = m_showSprite->getBoundingBox();
	Vec2 origin = this->convertToWorldSpace(rect.origin);
	return Rect(origin.x, origin.y, rect.size.width, rect.size.height);
}

Vec2 ArrowNode::getCollisionPoint() {
	return convertToWorldSpace(m_collisionPoint);
}

int ArrowNode::getAirSpeed() {
	return m_arrow->getSpeed();
}

int ArrowNode::getKnockBack() {
	return m_arrow->getKnockBack();
}

int ArrowNode::getRange() {
	return m_arrow->getRange();
}

void ArrowNode::setAirSpeed(int airSpeed) {
	m_arrow->setSpeed(airSpeed);
}

void ArrowNode::setKnockBack(int knockBack) {
	m_arrow->setKnockBack(knockBack);
}

void ArrowNode::setRange(int range) {
	m_arrow->setRange(range);
}